package com.kjc.demo.netty.client;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

import org.springframework.stereotype.Component;

import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

/**
 * @author kangjichang
 * @date 2022/7/28
 **/
@Component
@Slf4j
@ChannelHandler.Sharable
public class ResponseChannelHandler extends SimpleChannelInboundHandler<Object> {
	
	private final NioNettyClient nioNettyClient;
	
    public ResponseChannelHandler(NioNettyClient nioNettyClient) {
        this.nioNettyClient = nioNettyClient;
    }
	
	final static String CRLF = "\r\n";
	
    private String host;
    
    private Integer port;
    
    private Client client= null;
	
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    	log.info("channelActive -----------------------");
    	byte[] b = hexStringToBytes("00 01 00 00 00 06 01 01 00 02 00 08");
//    	ctx.writeAndFlush("00 01 00 00 00 06 01 01 00 02 00 08");
    	ctx.writeAndFlush(b);
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		 if (cause instanceof java.io.IOException) {
		     log.warn("exceptionCaught: client close");
	         log.warn("exceptionCaught:客户端[{}]和远程断开连接", ctx.channel().localAddress());
		 } else {
		     cause.printStackTrace();
		 }
		 ctx.pipeline().remove(this);
         ctx.channel().close();
         reconnection(ctx);
		 
         super.exceptionCaught(ctx, cause);
    }
    
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //如果运行过程中服务端挂了,执行重连机制
        log.info("start to reconnect netty server");
//        ctx.channel().eventLoop().schedule(() -> nioNettyClient.start(), 3L, TimeUnit.SECONDS);
        ctx.pipeline().remove(this);
        //ctx.close();
        ctx.channel().close();
        reconnection(ctx);
        super.channelInactive(ctx);
    }
    
    //执行重连逻辑
    private void reconnection(ChannelHandlerContext ctx) {
    	log.info("重连todo");
    	log.info("5s之后重新建立连接");
        ctx.channel().eventLoop().schedule(() -> nioNettyClient.start(), 5L, TimeUnit.SECONDS);
//		 ctx.channel().eventLoop().schedule(new Runnable() {
//		  @Override
//		  public void run() {
//		   boolean connect = client.start();
//		   if (connect) {
//		    log.info("重新连接成功");
//		   } else {
//		    reconnection(ctx);
//		   }
//		  }
//		 }, 5, TimeUnit.SECONDS);
    }
    
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
		// TODO Auto-generated method stub
		log.info("response info is {}", msg);
        //endregion
		
	}
	
	  /**

	1. * Convert byte[] to hex string.这里我们可以将byte转换成int，然后利用Integer.toHexString(int)来转换成16进制字符串。   
	2. * @param src byte[] data   
	3. * @return hex string   
	4. */      
	public static String bytesToHexString(byte[] src){   
	    StringBuilder stringBuilder = new StringBuilder("");   
	    if (src == null || src.length <= 0) {   
	        return null;   
	    }   
	    for (int i = 0; i < src.length; i++) {   
	        int v = src[i] & 0xFF;   
	        String hv = Integer.toHexString(v);   
	        if (hv.length() < 2) {   
	            stringBuilder.append(0);   
	        }   
	        stringBuilder.append(hv);   
	    }   
	    return stringBuilder.toString();   
	}   
	/**  
	21. * Convert hex string to byte[]  
	22. * @param hexString the hex string  
	23. * @return byte[]  
	24. */  
	public static byte[] hexStringToBytes(String hexString) {   
	    if (hexString == null || hexString.equals("")) {   
	        return null;   
	    }   
	    hexString = hexString.toUpperCase();   
	    int length = hexString.length() / 2;   
	    char[] hexChars = hexString.toCharArray();   
	    byte[] d = new byte[length];   
	    for (int i = 0; i < length; i++) {   
	        int pos = i * 2;   
	       d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));   
	    }   
	    return d;   
	}   
	/**  
	40. * Convert char to byte  
	41. * @param c char  
	42. * @return byte  
	43. */  
	private static byte charToByte(char c) {   
	    return (byte) "0123456789ABCDEF".indexOf(c);   
	}  


	//将指定byte数组以16进制的形式打印到控制台   
	public static void printHexString( byte[] b) {     
	  for (int i = 0; i < b.length; i++) {    
	     String hex = Integer.toHexString(b[i] & 0xFF);    
	     if (hex.length() == 1) {    
	       hex = '0' + hex;    
	     }    
	     System.out.print(hex.toUpperCase() );    
	  }    
	  
	}  

	 
}
